package ClientsAndHotels;

import jade.core.behaviours.CyclicBehaviour;
import jade.lang.acl.ACLMessage;
import jade.lang.acl.MessageTemplate;
import jade.lang.acl.UnreadableException;
import jade.wrapper.AgentController;
import jade.wrapper.ControllerException;
import jade.wrapper.StaleProxyException;

import java.util.Date;

import ClientsAndHotels.gui.GuiFrame;
import ClientsAndHotels.types.ClientParams;
import ClientsAndHotels.types.DiedAgentData;
import ClientsAndHotels.types.HotelParams;

public class GuiAgent extends CalendarObserverAgent {

    public static final String AGENT_DIED_CONVERSATION = "died";
    public static final String TYPE = "gui_agent";
    private GuiFrame frame;

    @Override
    protected void setup() {
        // Przywitaj się
        log("Przybył nowy agent GUI");

        frame = GuiFrame.startGui(this);

        addBehaviour(new CyclicBehaviour(this) {

            @Override
            public void action() {
                MessageTemplate mt = MessageTemplate.and(
                        MessageTemplate.MatchPerformative(ACLMessage.INFORM),
                        MessageTemplate.MatchConversationId("reservedRoom"));
                ACLMessage msg = myAgent.receive(mt);
                if (msg != null) {
                    String clientName = msg.getContent();
                    frame.markClientDone(clientName);
                }
                else {
                    block();
                }
            }
        });

        addBehaviour(new CyclicBehaviour(this) {

            @Override
            public void action() {
                MessageTemplate mt = MessageTemplate.and(MessageTemplate.and(
                        MessageTemplate.MatchPerformative(ACLMessage.INFORM),
                        MessageTemplate.MatchLanguage("JavaSerialization")),
                        MessageTemplate.MatchConversationId(AGENT_DIED_CONVERSATION));
                ACLMessage msg = myAgent.receive(mt);
                if (msg != null) {
                    try {
                        DiedAgentData data = (DiedAgentData) msg.getContentObject();
                        switch (data.getAgentType()) {
                            case DiedAgentData.TYPE_CLIENT:
                                frame.removeClient(data.getAgentName());
                                break;

                            case DiedAgentData.TYPE_MEDIATOR:
                                frame.removeMediator(data.getAgentName());
                                break;

                            case DiedAgentData.TYPE_HOTEL:
                                frame.removeHotel(data.getAgentName());
                                break;

                            default:
                                break;
                        }
                    } catch (UnreadableException e) {
                        e.printStackTrace();
                    }
                } else {
                    block();
                }
            }
        });
        super.setup();
    }

    @Override
    protected void takeDown() {
        frame.setVisible(false);
        super.takeDown();
    }

    public void createHotel(HotelParams hotel) throws StaleProxyException {
        AgentController controller = getContainerController().createNewAgent(
                hotel.getName(), HotelAgent.class.getName(),
                new Object[]{hotel});
        controller.start();
    }

    public void createClient(ClientParams client) throws StaleProxyException {
        AgentController controller = getContainerController().createNewAgent(
                client.getName(), ClientAgent.class.getName(),
                new Object[]{client});
        controller.start();
    }

    public void createMediator(String name) throws StaleProxyException {
        AgentController controller = getContainerController().createNewAgent(
                name, MediatorAgent.class.getName(), null);
        controller.start();
    }

    public void createCalendar(String name) throws StaleProxyException {
        AgentController controller = getContainerController().createNewAgent(
                name, CalendarAgent.class.getName(), null);
        controller.start();
    }

    public void killAgent(String name) throws ControllerException {
        AgentController controller = getContainerController().getAgent(name);
        controller.kill();
    }

    @Override
    protected void onDateChanged(Date date) {
        frame.setDate(date);
    }
}
